package com.lx.train.business.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ByteUtil;
import cn.hutool.core.util.EnumUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.ObjectUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lx.train.business.domain.*;
import com.lx.train.business.enums.SeatColEnum;
import com.lx.train.business.enums.SeatTypeEnum;
import com.lx.train.business.enums.TrainTypeEnum;
import com.lx.train.business.mapper.DailyTrainMapper;
import com.lx.train.business.mapper.DailyTrainSeatMapper;
import com.lx.train.common.resp.PageResp;
import com.lx.train.common.util.SnowUtil;
import com.lx.train.business.mapper.DailyTrainTicketMapper;
import com.lx.train.business.req.DailyTrainTicketQueryReq;
import com.lx.train.business.req.DailyTrainTicketSaveReq;
import com.lx.train.business.resp.DailyTrainTicketQueryResp;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;


@Slf4j
@Service
public class DailyTrainTicketService {
    @Autowired
    DailyTrainTicketMapper dailyTrainTicketMapper;
    @Autowired
    TrainStationService trainStationService;
    @Autowired
    private DailyTrainSeatService dailyTrainSeatService;

    /**
     * 新增和编辑操作
     * @param dailyTrainTicketSaveReq
     */
    public void saveDailyTrainTicket(DailyTrainTicketSaveReq dailyTrainTicketSaveReq) {
        DateTime now = DateTime.now();
        DailyTrainTicket dailyTrainTicket = BeanUtil.toBean(dailyTrainTicketSaveReq, DailyTrainTicket.class);
        if (dailyTrainTicket.getId() == null) {
            //为空则完成新增操作
            dailyTrainTicket.setId(SnowUtil.getSnowflakeNextId());
            dailyTrainTicket.setCreateTime(now);
            dailyTrainTicket.setUpdateTime(now);
            dailyTrainTicketMapper.insert(dailyTrainTicket);
        }else {
            //不为空则完成编辑操作
            dailyTrainTicket.setUpdateTime(now);
            dailyTrainTicketMapper.updateByPrimaryKey(dailyTrainTicket);
        }
    }

    /**
     * 查询操作
     * @param req
     */
    @Cacheable(value = "DailyTrainTicketService.queryList")
    public PageResp<DailyTrainTicketQueryResp> queryList(DailyTrainTicketQueryReq req) {
        DailyTrainTicketExample dailyTrainTicketExample = new DailyTrainTicketExample();
        DailyTrainTicketExample.Criteria criteria = dailyTrainTicketExample.createCriteria();
        if (ObjUtil.isNotNull(req.getDate())) {
            criteria.andDateEqualTo(req.getDate());
        }
        if (ObjUtil.isNotEmpty(req.getTrainCode())) {
            criteria.andTrainCodeEqualTo(req.getTrainCode());
        }
        if (ObjUtil.isNotEmpty(req.getStart())) {
            criteria.andStartEqualTo(req.getStart());
        }
        if (ObjUtil.isNotEmpty(req.getEnd())) {
            criteria.andEndEqualTo(req.getEnd());
        }

        log.info("查询页码：{}", req.getPage());
        log.info("每页条数：{}", req.getSize());
        PageHelper.startPage(req.getPage(), req.getSize());
        List<DailyTrainTicket> dailyTrainTicketList = dailyTrainTicketMapper.selectByExample(dailyTrainTicketExample);

        PageInfo<DailyTrainTicket> pageInfo = new PageInfo<>(dailyTrainTicketList);
        log.info("总行数：{}", pageInfo.getTotal());
        log.info("总页数：{}", pageInfo.getPages());

        List<DailyTrainTicketQueryResp> list = BeanUtil.copyToList(dailyTrainTicketList, DailyTrainTicketQueryResp.class);

        PageResp<DailyTrainTicketQueryResp> pageResp = new PageResp<>();
        pageResp.setTotal(pageInfo.getTotal());
        pageResp.setList(list);
        return pageResp;
    }

    /**
     * 删除操作
     * @param id
     */
    public void delete(Long id) {
        dailyTrainTicketMapper.deleteByPrimaryKey(id);
    }

    @Transactional
    public void genDaily(DailyTrain dailyTrain ,Date date , String trainCode){
        //计算票价系数
        String type = dailyTrain.getType();
        BigDecimal priceRate = EnumUtil.getFieldBy(TrainTypeEnum::getPriceRate, TrainTypeEnum::getCode, type);
        //删除某日车次的余票信息
        DailyTrainTicketExample dailyTrainTicketExample = new DailyTrainTicketExample();
        dailyTrainTicketExample.createCriteria()
                .andDateEqualTo(date)
                .andTrainCodeEqualTo(trainCode);
        dailyTrainTicketMapper.deleteByExample(dailyTrainTicketExample);
        //查询途径车站信息
        //查出某车次所有车站信息
        List<TrainStation> trainStations = trainStationService.selectTrainCode(trainCode);
        if (ObjUtil.isEmpty(trainStations)) {
            log.info("该车次没有余票,生成车次余票信息信息结束");
            return;
        }
        DateTime now = DateTime.now();
        for (int i = 0; i < trainStations.size(); i++) {
            //得到出发站
            TrainStation trainStationStart = trainStations.get(i);
            BigDecimal sumKM = BigDecimal.ZERO;
            for (int j = i + 1; j < trainStations.size(); j++) {
                //计算票余量
                int ydz = dailyTrainSeatService.countSeat(trainCode , date , SeatTypeEnum.YDZ.getCode());
                int edz = dailyTrainSeatService.countSeat(trainCode , date , SeatTypeEnum.EDZ.getCode());
                int rw = dailyTrainSeatService.countSeat(trainCode , date , SeatTypeEnum.RW.getCode());
                int yw = dailyTrainSeatService.countSeat(trainCode , date , SeatTypeEnum.YW.getCode());
                //票价 = 里程之和 * 座位单价 * 车次类型系数
                TrainStation trainStationEnd = trainStations.get(j);
                sumKM = sumKM.add(trainStationEnd.getKm());
                //计算票价
                BigDecimal yzdPrice = sumKM.multiply(SeatTypeEnum.YDZ.getPrice()).multiply(priceRate).setScale(2, RoundingMode.HALF_UP);
                BigDecimal ezdPrice = sumKM.multiply(SeatTypeEnum.EDZ.getPrice()).multiply(priceRate).setScale(2, RoundingMode.HALF_UP);
                BigDecimal rwPrice = sumKM.multiply(SeatTypeEnum.RW.getPrice()).multiply(priceRate).setScale(2, RoundingMode.HALF_UP);
                BigDecimal ywPrice = sumKM.multiply(SeatTypeEnum.YW.getPrice()).multiply(priceRate).setScale(2, RoundingMode.HALF_UP);
                DailyTrainTicket dailyTrainTicket = new DailyTrainTicket();
                dailyTrainTicket.setId(SnowUtil.getSnowflakeNextId());
                dailyTrainTicket.setDate(date);
                dailyTrainTicket.setTrainCode(trainCode);
                dailyTrainTicket.setStart(trainStationStart.getName());
                dailyTrainTicket.setStartPinyin(trainStationStart.getNamePinyin());
                dailyTrainTicket.setStartTime(trainStationStart.getOutTime());
                dailyTrainTicket.setStartIndex(trainStationStart.getIndex());
                dailyTrainTicket.setEnd(trainStationEnd.getName());
                dailyTrainTicket.setEndPinyin(trainStationEnd.getNamePinyin());
                dailyTrainTicket.setEndTime(trainStationEnd.getInTime());
                dailyTrainTicket.setEndIndex(trainStationEnd.getIndex());
                dailyTrainTicket.setYdz(ydz);
                dailyTrainTicket.setYdzPrice(yzdPrice);
                dailyTrainTicket.setEdz(edz);
                dailyTrainTicket.setEdzPrice(ezdPrice);
                dailyTrainTicket.setRw(rw);
                dailyTrainTicket.setRwPrice(rwPrice);
                dailyTrainTicket.setYw(yw);
                dailyTrainTicket.setYwPrice(ywPrice);
                dailyTrainTicket.setCreateTime(now);
                dailyTrainTicket.setUpdateTime(now);
                dailyTrainTicketMapper.insert(dailyTrainTicket);
            }
        }
    }

    /**
     * 按唯一键查询余票量
     * @param
     * @param
     * @return
     */
    public DailyTrainTicket selectByUnique(Date date ,String trainCode , String start ,
                                            String end){
        DailyTrainTicketExample example = new DailyTrainTicketExample();
        example.createCriteria()
                .andTrainCodeEqualTo(trainCode)
                .andDateEqualTo(date)
                .andStartEqualTo(start)
                .andEndEqualTo(end);
        List<DailyTrainTicket> list = dailyTrainTicketMapper.selectByExample(example);
        if (list != null && list.size() > 0) {
            return list.get(0);
        }else{
            return null;
        }
    }
}
